home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / footchmp.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  11KB  |  424 lines

  1. #include "driver.h"
  2. #include "vidhrdw/generic.h"
  3.  
  4. unsigned char *footchmp_chargen_ram, *footchmp_text_ram;
  5. unsigned char *footchmp_layer0_ram, *footchmp_layer1_ram;
  6. unsigned char *footchmp_layer2_ram, *footchmp_layer3_ram;
  7.  
  8. static unsigned char *char_dirty;
  9. static struct tilemap *text_layer, *layer0_map, *layer1_map, *layer2_map, *layer3_map;
  10.  
  11. static int spritebank[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  12.  
  13. /***************************************************************************
  14.  
  15.     Layers
  16.  
  17. ***************************************************************************/
  18.  
  19. /* Callbacks */
  20. #define LAYER_CALLBACK( layer_name ) \
  21.     static void layer_name##_map_info( int tile_index ) { \
  22.         int data0 = READ_WORD( &footchmp_##layer_name##_ram[4*tile_index] ); \
  23.         int data1 = READ_WORD( &footchmp_##layer_name##_ram[4*tile_index+2] ); \
  24.         tile_info.flags = TILE_FLIPYX( ( data0 & 0xc000 ) >> 14 ); \
  25.         SET_TILE_INFO( 0, data1 & 0x1fff, data0 & 0xff ); \
  26.     }
  27.  
  28. LAYER_CALLBACK( layer0 )
  29. LAYER_CALLBACK( layer1 )
  30. LAYER_CALLBACK( layer2 )
  31. LAYER_CALLBACK( layer3 )
  32.  
  33. static void text_layer_info( int tile_index )
  34. {
  35.     int data = READ_WORD( &footchmp_text_ram[2*tile_index] );
  36.  
  37.     tile_info.flags = TILE_FLIPYX( ( data & 0xc000 ) >> 14 );
  38.  
  39.     /* set code and color */
  40.     SET_TILE_INFO( 2, data & 0xff, ( data & 0x3f00 ) >> 8 );
  41. }
  42.  
  43. #define LAYER_READ( layer_name ) \
  44.     READ_HANDLER( footchmp_##layer_name##ram_r ) { \
  45.         return READ_WORD( &footchmp_##layer_name##_ram[offset] ); \
  46.     }
  47.  
  48. #define LAYER_WRITE( layer_name ) \
  49.     WRITE_HANDLER( footchmp_##layer_name##ram_w ) { \
  50.         int oldword = READ_WORD (&footchmp_##layer_name##_ram[offset]); \
  51.         int newword = COMBINE_WORD (oldword,data); \
  52.         if (oldword != newword) \
  53.         { \
  54.             WRITE_WORD (&footchmp_##layer_name##_ram[offset],newword); \
  55.             tilemap_mark_tile_dirty( layer_name##_map, offset/4 ); \
  56.         } \
  57.     }
  58.  
  59. LAYER_READ( layer0 )
  60. LAYER_READ( layer1 )
  61. LAYER_READ( layer2 )
  62. LAYER_READ( layer3 )
  63. LAYER_WRITE( layer0 )
  64. LAYER_WRITE( layer1 )
  65. LAYER_WRITE( layer2 )
  66. LAYER_WRITE( layer3 )
  67.  
  68. /***************************************************************************
  69.  
  70.     Character Generator + Text Layer
  71.  
  72. ***************************************************************************/
  73.  
  74. READ_HANDLER( footchmp_textram_r ) {
  75.     return READ_WORD( &footchmp_text_ram[offset] );
  76. }
  77.  
  78. WRITE_HANDLER( footchmp_textram_w ) {
  79.     int oldword = READ_WORD (&footchmp_text_ram[offset]);
  80.     int newword = COMBINE_WORD (oldword,data);
  81.  
  82.     if (oldword != newword)
  83.     {
  84.         WRITE_WORD (&footchmp_text_ram[offset],newword);
  85.         tilemap_mark_tile_dirty( text_layer, offset/2 );
  86.     }
  87. }
  88.  
  89. /* we have to straighten out the 16-bit word into bytes for gfxdecode() to work */
  90. READ_HANDLER( footchmp_chargen_r ) {
  91.     int res;
  92.  
  93.     res = READ_WORD (&footchmp_chargen_ram[offset]);
  94.  
  95.     #ifdef LSB_FIRST
  96.     res = ((res & 0x00ff) << 8) | ((res & 0xff00) >> 8);
  97.     #endif
  98.  
  99.     return res;
  100. }
  101.  
  102. WRITE_HANDLER( footchmp_chargen_w ) {
  103.     int oldword = READ_WORD (&footchmp_chargen_ram[offset]);
  104.     int newword;
  105.  
  106.  
  107.     #ifdef LSB_FIRST
  108.     data = ((data & 0x00ff00ff) << 8) | ((data & 0xff00ff00) >> 8);
  109.     #endif
  110.  
  111.     newword = COMBINE_WORD (oldword,data);
  112.     if (oldword != newword)
  113.     {
  114.         WRITE_WORD (&footchmp_chargen_ram[offset],newword);
  115.         char_dirty[offset/32] = 1;
  116.     }
  117. }
  118.  
  119. /***************************************************************************
  120.  
  121.     Sprites
  122.  
  123. ***************************************************************************/
  124.  
  125. READ_HANDLER( footchmp_spriteram_r ) {
  126.     return READ_WORD( &spriteram[offset] );
  127. }
  128.  
  129. WRITE_HANDLER( footchmp_spriteram_w ) {
  130.     COMBINE_WORD_MEM( &spriteram[offset], data );
  131. }
  132.  
  133. WRITE_HANDLER( footchmp_spritebank_w ) {
  134.     logerror("PC = %06x: bank %d, new value: %04x\n", cpu_get_pc(), offset >> 1, ( data & 0x0f ) << 10);
  135. //    if ( ( offset >> 1 ) < 2 ) return;
  136. //    if ( data == 0 ) data = ( ( offset >> 1 ) * 0x400 ) >> 10;
  137.     spritebank[offset >> 1] = data & 0x0f;
  138. }
  139.  
  140. #define CONVERT_SPRITE_CODE                                                \
  141. {                                                                        \
  142.     int bank;                                                            \
  143.                                                                         \
  144.     bank = (code & 0x1800) >> 11;                                        \
  145.     switch (bank)                                                        \
  146.     {                                                                    \
  147.         case 0: code = spritebank[2] * 0x800 + (code & 0x7ff); break;    \
  148.         case 1: code = spritebank[3] * 0x800 + (code & 0x7ff); break;    \
  149.         case 2: code = spritebank[4] * 0x400 + (code & 0x7ff); break;    \
  150.         case 3: code = spritebank[6] * 0x800 + (code & 0x7ff); break;    \
  151.     }                                                                    \
  152. }                                                                        \
  153.  
  154.  
  155. static void footchmp_mark_sprite_colors( void ) {
  156.     unsigned short palette_map[256];
  157.     int code, color, offs, i;
  158.  
  159.     memset (palette_map, 0, sizeof (palette_map));
  160.  
  161.     for ( offs = 0x30; offs < 0x8000; offs += 16 ) {
  162.         code = READ_WORD(&spriteram[offs]);
  163.         CONVERT_SPRITE_CODE;
  164.         color = READ_WORD(&spriteram[offs+8]) & 0x00ff;
  165.  
  166.         palette_map[color] |= Machine->gfx[1]->pen_usage[code];
  167.     }
  168.  
  169.     /* now build the final table */
  170.     for ( i = 0; i < 256; i++ )
  171.     {
  172.         int usage = palette_map[i], j;
  173.         if (usage)
  174.         {
  175.             for (j = 1; j < 16; j++)
  176.                 if (usage & (1 << j))
  177.                     palette_used_colors[i * 16 + j] |= PALETTE_COLOR_VISIBLE;
  178.         }
  179.     }
  180. }
  181.  
  182. static void footchmp_drawsprites( struct osd_bitmap *bitmap ) {
  183.     /*
  184.  
  185.         from vidhrdw/taitof2.c
  186.  
  187.         Sprite format:
  188.         0000: 000xxxxxxxxxxxxx: tile code (0x0000 - 0x1fff)
  189.         0002: unused?
  190.         0004: 0000xxxxxxxxxxxx: x-coordinate absolute (-0x1ff to 0x01ff)
  191.               0x00000000000000: don't compensate for scrolling ??
  192.         0006: 0000xxxxxxxxxxxx: y-coordinate absolute (-0x1ff to 0x01ff)
  193.         0008: 00000000xxxxxxxx: color (0x00 - 0xff)
  194.               000000xx00000000: flipx & flipy
  195.               00000x0000000000: if clear, latch x & y coordinates, tile & color ?
  196.               0000x00000000000: if set, next sprite entry is part of sequence
  197.               000x000000000000: if clear, use latched y coordinate, else use current y
  198.               00x0000000000000: if set, y += 16
  199.               0x00000000000000: if clear, use latched x coordinate, else use current x
  200.               x000000000000000: if set, x += 16
  201.         000a - 000f : unused?
  202.  
  203.         Additionally, the first 3 sprite entries are configuration info instead of
  204.         actual sprites:
  205.  
  206.         offset 0x24: sprite x offset
  207.         offset 0x26: sprite y offset
  208.     */
  209.     int x,y,offs,code,color,spritecont,flipx,flipy;
  210.     int xcurrent,ycurrent;
  211.     int scroll1x, scroll1y;
  212.     int scrollx=0, scrolly=0;
  213.     int curx,cury;
  214.  
  215.     scroll1x = READ_WORD(&spriteram[0x24]);
  216.     scroll1y = READ_WORD(&spriteram[0x26]);
  217.  
  218.     x = y = 0;
  219.     xcurrent = ycurrent = 0;
  220.     color = 0;
  221.  
  222.     for (offs = 0x30;offs < 0x8000;offs += 16)
  223.     {
  224.         spritecont = (READ_WORD(&spriteram[offs+8]) & 0xff00) >> 8;
  225.  
  226.         if ((spritecont & 0xf4) == 0)
  227.         {
  228.             x = READ_WORD(&spriteram[offs+4]);
  229.             if (x & 0x4000)
  230.             {
  231.                 scrollx = 0;
  232.                 scrolly = 0;
  233.             }
  234.             else
  235.             {
  236.                 scrollx = scroll1x;
  237.                 scrolly = scroll1y;
  238.             }
  239.             x &= 0x1ff;
  240.             y = READ_WORD(&spriteram[offs+6]) & 0x01ff;
  241.             color = READ_WORD(&spriteram[offs+8]) & 0x00ff;
  242.  
  243.             xcurrent = x;
  244.             ycurrent = y;
  245.         }
  246.         else
  247.         {
  248.             if ((spritecont & 0x10) == 0)
  249.                 y = ycurrent;
  250.             else if ((spritecont & 0x20) != 0)
  251.                 y += 16;
  252.  
  253.             if ((spritecont & 0x40) == 0)
  254.                 x = xcurrent;
  255.             else if ((spritecont & 0x80) != 0)
  256.                 x += 16;
  257.         }
  258.  
  259.         code = READ_WORD(&spriteram[offs]);
  260.         if (!code) continue;
  261.  
  262.         CONVERT_SPRITE_CODE;
  263.  
  264.         flipx = spritecont & 0x01;
  265.         flipy = spritecont & 0x02;
  266.  
  267.         // AJP (fixes sprites off right side of screen)
  268.         curx = (x + scrollx) & 0x1ff;
  269.         if (curx>0x140) curx -= 0x200;
  270.         cury = (y + scrolly) & 0x1ff;
  271.         if (cury>0x100) cury -= 0x200;
  272.  
  273.         drawgfx (bitmap,Machine->gfx[1],
  274.                 code,
  275.                 color,
  276.                 flipx,flipy,
  277.                 curx,cury,
  278.                 0,TRANSPARENCY_PEN,0);
  279.     }
  280. }
  281.  
  282. /***************************************************************************
  283.  
  284.     Video Control (scroll,zoom)
  285.  
  286. ***************************************************************************/
  287.  
  288. WRITE_HANDLER( footchmp_scroll_w ) {
  289.  
  290.     /* scroll values are adjusted at PC $8BA */
  291.  
  292.     switch( offset ) {
  293.         case 0x00:
  294.             data = ~( data - 33 ); /* adjust x scroll */
  295.             tilemap_set_scrollx( layer0_map, 0, data );
  296.         break;
  297.  
  298.         case 0x02:
  299.             data = ~( data - 29 ); /* adjust x scroll */
  300.             tilemap_set_scrollx( layer1_map, 0, data );
  301.         break;
  302.  
  303.         case 0x04:
  304.             data = ~( data - 25 ); /* adjust x scroll */
  305.             tilemap_set_scrollx( layer2_map, 0, data );
  306.         break;
  307.  
  308.         case 0x06:
  309.             data = ~( data - 21 ); /* adjust x scroll */
  310.             tilemap_set_scrollx( layer3_map, 0, data );
  311.         break;
  312.  
  313.         case 0x08:
  314.             data += 8; /* adjust y scroll */
  315.             tilemap_set_scrolly( layer0_map, 0, data );
  316.         break;
  317.  
  318.         case 0x0a:
  319.             data += 8; /* adjust y scroll */
  320.             tilemap_set_scrolly( layer1_map, 0, data );
  321.         break;
  322.  
  323.         case 0x0c:
  324.             data += 8; /* adjust y scroll */
  325.             tilemap_set_scrolly( layer2_map, 0, data );
  326.         break;
  327.  
  328.         case 0x0e:
  329.             data += 8; /* adjust y scroll */
  330.             tilemap_set_scrolly( layer3_map, 0, data );
  331.         break;
  332.  
  333.         case 0x10: /* layer 0 zoom */
  334.         case 0x12: /* layer 1 zoom */
  335.         case 0x14: /* layer 2 zoom */
  336.         case 0x16: /* layer 3 zoom */
  337.         break;
  338.  
  339.         case 0x18:
  340.             data = ~( data - 35 ); /* adjust x scroll */
  341.             tilemap_set_scrollx( text_layer, 0, data );
  342.         break;
  343.  
  344.         case 0x1a:
  345.             data = ~( data - 9 ); /* adjust y scroll (inverted for this layer) */
  346.             tilemap_set_scrolly( text_layer, 0, data );
  347.         break;
  348.     }
  349. }
  350.  
  351. /***************************************************************************
  352.  
  353.     MAME functions
  354.  
  355. ***************************************************************************/
  356.  
  357. void footchmp_vh_screenrefresh( struct osd_bitmap *bitmap, int full_refresh ) {
  358.     int        i, inval = 1;
  359.  
  360.     /* Update character generator */
  361.     for ( i = 0; i < 256; i++ ) {
  362.         if ( char_dirty[i] ) {
  363.             decodechar (Machine->gfx[2],i,footchmp_chargen_ram, Machine->drv->gfxdecodeinfo[2].gfxlayout);
  364.             char_dirty[i] = 0;
  365.             /* We must invalidate all the layer's tiles (do it only once per dirty scan) */
  366.             if ( inval ) {
  367.                 tilemap_mark_all_tiles_dirty(text_layer);
  368.                 inval = 0;
  369.             }
  370.         }
  371.     }
  372.  
  373.     tilemap_update( ALL_TILEMAPS );
  374.  
  375.     palette_init_used_colors();
  376.  
  377.     footchmp_mark_sprite_colors();
  378.  
  379.     if (palette_recalc())
  380.         tilemap_mark_all_pixels_dirty(ALL_TILEMAPS);
  381.  
  382.     tilemap_render(ALL_TILEMAPS);
  383.  
  384.     tilemap_draw(bitmap, layer0_map, 0 );
  385.     tilemap_draw(bitmap, layer1_map, 0 );
  386.     tilemap_draw(bitmap, layer2_map, 0 );
  387.     tilemap_draw(bitmap, layer3_map, 0 );
  388.     footchmp_drawsprites( bitmap );
  389.     tilemap_draw(bitmap, text_layer, 0 );
  390. }
  391.  
  392. int footchmp_vh_start( void )
  393. {
  394.     char_dirty = malloc( 256 );
  395.  
  396.     if ( char_dirty == 0 )
  397.         return 1;
  398.  
  399.     memset( char_dirty, 1, 256 );
  400.  
  401.     text_layer = tilemap_create(text_layer_info,tilemap_scan_rows,TILEMAP_TRANSPARENT, 8, 8,64,64);
  402.     layer3_map = tilemap_create(layer3_map_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,32,32);
  403.     layer2_map = tilemap_create(layer2_map_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,32,32);
  404.     layer1_map = tilemap_create(layer1_map_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,32,32);
  405.     layer0_map = tilemap_create(layer0_map_info,tilemap_scan_rows,TILEMAP_OPAQUE,     16,16,32,32);
  406.  
  407.     if ( !text_layer || !layer3_map || !layer2_map || !layer1_map || !layer0_map )
  408.     {
  409.         free( char_dirty );
  410.         return 1;
  411.     }
  412.  
  413.     text_layer->transparent_pen = 0;
  414.     layer3_map->transparent_pen = 0;
  415.     layer2_map->transparent_pen = 0;
  416.     layer1_map->transparent_pen = 0;
  417.  
  418.     return 0;
  419. }
  420.  
  421. void footchmp_vh_stop( void ) {
  422.     free( char_dirty );
  423. }
  424.